package com.self.ry.utils.lambda;

import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SalaryTest {

	public static void main(String[] args) throws Exception{
		long current = System.currentTimeMillis();
		
		String path = "src/com/my/reflect/test.txt";
		write(path);
		reader(path);
		
		long current2 = System.currentTimeMillis();
		System.out.println(current2 - current);
		
		
		//Collector.of(supplier, accumulator, combiner, finisher, characteristics)
	}
	
	public static void write(String path) throws Exception{
		try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));){
			Random random = new Random();
			for (int i = 0; i < 10000000; i++) {
				writer.write(Salary.getRandomString(4)+","+
                        random.nextInt(101)+","+random.nextInt(6));
                writer.newLine();
			}
			
			writer.flush();
		} finally {
			System.out.println("write ok");
		}
	}
	
	public static void reader(String path) throws Exception{
		try(BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "UTF-8"));){
            Stream<String> lines = reader.lines();
            List<Salary> list = getListFromStream(lines);
            lines = null;

            List<Salary> list2 = list.parallelStream().sorted(Comparator.comparing(Salary::getTotalSalary).reversed()).limit(10).collect(Collectors.toList());
            list = null;
            System.out.println(list2);
        } finally {
            System.out.println("reader finish");
        }
	}
	
	public static List<Salary> getListFromStream(Stream<String> accounts) {
		
		Function<Salary, String> finisher = (s) -> {
			return s.getNumber() + s.getName();
		};
		
        Map<String, DoubleSummaryStatistics> collect = accounts.map(m -> {
            String[] strings = m.split(",");

            return new Salary() {{
                setNumber(1);
                setName(strings[0].substring(0, 2));
                setTotalSalary(new BigDecimal(strings[1]).multiply(new BigDecimal("13")).add(new BigDecimal(strings[2])).doubleValue());
            }};
        }).collect(Collectors.groupingBy(Salary::getName,
                // Collectors.summingDouble(Salary::getTotalSalary) // Map<String, Double>
                Collectors.summarizingDouble(Salary::getTotalSalary) // Map<String, DoubleSummaryStatistics>
                // Collectors.toList()
                //Tuple.collectors(collector1, collector2)
                ));
		
		
		/*Map<String, Tuple2<DoubleSummaryStatistics, DoubleSummaryStatistics>> collect = accounts.map(m -> {
            String[] strings = m.split(",");

            return new Salary() {{
                setNumber(1);
                setName(strings[0].substring(0, 2));
                setTotalSalary(new BigDecimal(strings[1]).multiply(new BigDecimal("13")).add(new BigDecimal(strings[2])).doubleValue());
            }};
        }).collect(Collectors.groupingBy(Salary::getName,
                Tuple.collectors(Collectors.summarizingDouble(Salary::getTotalSalary), Collectors.summarizingDouble(Salary::getNumber))
                ));*/
		
        List<Salary> list = new ArrayList<>();
        collect.forEach((k, v) -> {
            Salary salary = new Salary();
            salary.setName(k);
            salary.setNumber(v.getCount());
            salary.setTotalSalary(v.getSum());
            list.add(salary);
        });

        return list;
    }
}
